/*
 * @Author: ylq
 * @Date: 2021-08-23 16:47:12
 * @Desc: Axios
 * @Last Modified by: ylq
 * @Last Modified time: 2022-06-29 21:22:05
 */

import axios from 'axios'
import Vue from 'vue'
import con from '../config/config'
import storage from './storage'
import qs from 'qs'
import router from '@/router'
import store from '@/store'
import { tools } from './tools'

// --阻止重复发送请求----------------------------------------------------------------------------------
let pending = [] //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let cancelToken = axios.CancelToken
let removePending = (ever) => {
  for (let p in pending) {
    let apiIndex = ever.params && ever.params.apiIndex
    let u = ever.url + '&' + ever.method
    if (apiIndex) {
      u += '&' + apiIndex
    }
    if (pending[p].u === u) {
      //当当前请求在数组中存在时执行函数体
      pending[p].f() //执行取消操作
      pending.splice(p, 1) //把这条记录从数组中移除
    }
  }
}
// --阻止重复发送请求----------------------------------------------------------------------------------

// json格式 payload
// let jsonHeaders = {
//   'Content-Type': 'application/json',
//   'X-Requested-With': 'XMLHttpRequest',
// }
// 创建一个新的axios实例
let http = axios.create({
  baseURL: '/',
  headers: {
    // formData 格式
    // 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
    // payload格式
    'Content-Type': 'application/json',
  },
  withCredentials: false,
  // transformRequest: [(data) => {
  //   // let td = 'data=' + encodeURIComponent(JSON.stringify(data))
  //   // console.log(td);
  //   // return JSON.stringify(data)
  //   return data
  // }],
  paramsSerializer: function (params) {
    // params = {data: params}
    return qs.stringify(params, { arrayFormat: 'brackets' })
    // return params
  },
  // 用于对相应数据进行处理
  // 它会通过then或者catch
  transformResponse: [
    function (data) {
      // 可以对data做任何操作
      //   let res = {
      //     error: null,
      //     paging: null,
      //     result: null,
      //   }
      try {
        data = JSON.parse(data)
        let head = {
          Code: data.code,
          Msg: data.msg,
        }

        let err = null
        if (head && head.Code !== 200) {
          err = { msg: head.Msg, code: head.Code }
        }
        let paging = null
        let result = data.data
        if (result && result.page_info && result != null) {
          paging = result.page_info
          result = result.list
        }
        let myData = {
          error: err || null,
          paging,
          result: result || null,
        }
        return myData
      } catch {
        return data
      }
    },
  ],
})

// 添加请求拦截器
http.interceptors.request.use(
  (config) => {
    // loading
    // 发送请求类型，默认改为post
    // config.mt ? config.method = config.mt : config.method = 'POST';
    // 发送数据格式 json  如果需要form/data 增加hdt 属性，值为fd
    // if (config.headers["Content-Type"] === "multipart/form-data") {
    //   console.log(config.headers)
    //   // config.headers = fdHeaders
    // }
    // 获取token
    // let token = storage.getItem(con.TOKEN) || null;
    // if (token) {
    //   config.headers['Access-Token'] = token
    // }
    // 获取token
    // let token = storage.getItem(con.TOKEN) || null;
    let token = tools.getCookie(con.COOKIE_NAME) || null
    if (token) {
      config.headers['token'] = token
      config.headers['authorization'] = `Bearer ${token}`
    }
    // console.log(token)
    // 提交数据格式转化
    // console.log(config)
    // ------------------------------------------------------------------------------------
    removePending(config) //在一个ajax发送前执行一下取消操作
    config.cancelToken = new cancelToken((c) => {
      let apiIndex = config.params && config.params.apiIndex
      // 这里的ajax标识我是用请求地址&请求方式拼接的字符串，当然你可以选择其他的一些方式
      let u = config.url + '&' + config.method
      if (apiIndex) {
        u += '&' + apiIndex
      }
      //  console.log(u)
      pending.push({ u, f: c })
    })
    // ------------------------------------------------------------------------------------

    return config
  },
  (err) => {
    return Promise.reject(err)
  },
)

// 添加响应拦截器
http.interceptors.response.use(
  (response) => {
    // ------------------------------------------------------------------------------------------
    removePending(response.config) //在一个ajax响应后再执行一下取消操作，把已经完成的请求从pending中移除
    // -------------------------------------------------------------------------------------------
    let rd = response.data
    // console.log(145,JSON.stringify(rd))
    if (rd.error && rd.error.code == 13) {
      store.dispatch('logout')
      setTimeout(() => {
        storage.removeItem(con.USERINFO)
        storage.removeItem(con.TOKEN)
        tools.setCookie(con.COOKIE_NAME, 0, -1)
        // localStorage.removeItem('user')
        // localStorage.removeItem('token')
      }, 1000)
      router.replace({
        path: '/',
        query: { back: router.currentRoute.fullPath },
      })
      // window.location.href = '/';
    } else {
      // 存储当前时间
      storage.setItem(con.LAST_LOGIN_TIME, Date.now())
    }
    return rd
  },
  (error) => {
    return Promise.reject(error)
  },
)

// 导出 为插件
export default {
  install() {
    Vue.prototype.$http = http
    Vue.http = http
  },
}

// 导出axios
export { http as axios }
